<template>
	<view class="">
		<view @click="checkImg">
			<slot>
				<view style="padding: 15px 10px;">选择图片</view>
			</slot>
		</view>
		<view class="page-view" v-if="imageSrc">
			<view class="content-view" @mousedown.stop="mousedown" @mousemove.stop="mousemove" @mouseup.stop="mouseup"  @touchstart.stop.prevent="touchstart" @touchmove.stop.prevent="touchmove"
				@touchend.stop.prevent="touchend">
				<view class="img-view">
					<image :class="['img', imgTransition && 'imgTransitionName']"
						:style="{transform: transformText,width: pageHW.width+'px', height: imgH +'px'}" :src="imageSrc"
						mode=""></image>
				</view>
				<view class="round-view" :style="{borderRadius: circle ? '50%' : 'none'}">
					<image :class="['round-img', imgTransition && 'imgTransitionName']"
						:style="{transform: transformText,top: -(roundHW.top - pageHW.top)+'px',maxWidth: pageHW.width+'px',width: pageHW.width + 'px', height: imgH +'px'}"
						:src="imageSrc" mode=""></image>
				</view>
			</view>
			<view class="footer-vtn">
				<view class="cancel-btn" @click="handleCancel">
					取消
				</view>
				<view class="confirm-btn" @click="handleConfirm">
					确定
				</view>
			</view>
			<canvas canvas-id="myCanvas"
				:style="'position:absolute;border: 1px solid red; width:'+roundW+'px;height:'+roundW+'px;top:-9999px;left:-9999px;'"></canvas>
		</view>
	</view>
</template>

<script>
	export default {
		props:{
			circle:{
				type: [Boolean],
				default: false
			},
			src:{
				type: [String],
				default: ''
			}
		},
		data() {
			return {
				// 是否使用动画过度
				imgTransition: true,
				// 移动位置
				transformText: '',
				// 图片与屏幕的比列
				percentage: 0,
				// 圆的大小
				roundW: null,
				roundHW: {
					width: 0
				},
				// 页面的宽度
				pageHW: {
					width: 0
				},
				// 图片的路径
				imageSrc: null,
				// 图片的高度
				imgH: 0,
				// y轴方向的移动距离
				imgMoveY: 0,
				// x轴方向的移动距离
				imgMoveX: 0,
				// 上一次的移动距离
				oldTop: 0,
				oldLeft: 0,
				// 上下能移动的最大范围
				imgMaxTop: 0,
				// 左右能移动的最大范围
				imgMaxLeft: 0,
				// 手指开始的坐标
				touchstartTouches: [],
				imgMoveT: 0,
				imgMoveB: 0,
				imgMoveL: 0,
				imgMoveR: 0,
				// 图片初始移动距离
				initData: {
					top: 0,
					left: 0
				}
			}
		},
		mounted() {

		},
		methods: {
			// 获取高度
			getDom() {
				return new Promise((relove, reject) => {
					uni.createSelectorQuery().in(this).select('.content-view').boundingClientRect((rect) => {
						this.pageHW = rect;
						console.log(rect, 'aaaa')
						uni.createSelectorQuery().in(this).select('.round-view').boundingClientRect((
							rect) => {
							this.roundW = rect.width;
							this.roundHW = rect;
							console.log(rect, 'bb')
							relove()
						}).exec()
					}).exec()
				})

			},
			checkImg() {
				const _this = this;
				uni.chooseImage({
					count: 1,
					success(res) {
						uni.getImageInfo({
							src: res.tempFilePaths[0],
							success: function success(res) {
								_this.imageSrc = res.path;
								_this.$nextTick(() => {
									_this.getDom().then(e => {
										_this.getImgWH(res)
									})
								})

							}
						})
					}
				})
			},
			// 获取选择图片的高宽
			getImgWH(img) {
				// 图片的实际宽度与屏幕宽度的比列
				this.percentage = img.width / this.pageHW.width;
				// 显示图片的高度
				this.imgH = img.height / this.percentage;
				// 图片向上的初始偏移量
				this.imgMoveY = (this.pageHW.height - this.imgH) / 2;
				// 初始移动距离上不会改变的数据
				this.initData.top = (this.pageHW.height - this.imgH) / 2;
				// 图片移动的最大距离左右
				this.imgMaxLeft = (this.pageHW.width - this.roundW) / 2;
				// 图片移动的最大距离上下
				this.imgMaxTop = (this.imgH - this.roundW) / 2;
				this.imgMoveT = this.imgMoveY - this.imgMaxTop;
				this.imgMoveB = this.imgMoveY + this.imgMaxTop;
				this.imgMoveL = -this.imgMaxLeft;
				this.imgMoveR = this.imgMaxLeft;
				this.setTransform();
			},
			// 设置图片移动距离
			setTransform() {
				this.transformText = `translate3d(${this.imgMoveX}px, ${this.imgMoveY}px,  0)`;
			},
			// 开始点击
			_down(data){
				this.imgTransition = !this.imgTransition;
				this.touchstartTouches = data;
				this.oldTop = Number(this.imgMoveY);
				this.oldLeft = Number(this.imgMoveX);
			},
			_move(e){
				this.imgMoveY = this.oldTop + (e[0].pageY - this.touchstartTouches[0].pageY)
				this.imgMoveX = this.oldLeft + (e[0].pageX - this.touchstartTouches[0].pageX)
				this.setTransform()
			},
			_end(e){
				// 宽度没有限制
				if (this.imgMoveX > this.imgMoveR) {
					this.imgMoveX = this.imgMoveR
				}
				if (this.imgMoveX < this.imgMoveL) {
					this.imgMoveX = this.imgMoveL
				}
				// 高度大于目标大小
				if (this.imgH >= this.roundW) {
					if (this.imgMoveY < this.imgMoveT) {
						this.imgMoveY = this.imgMoveT
					}
					if (this.imgMoveY > this.imgMoveB) {
						this.imgMoveY = this.imgMoveB
					}
				}else{
					if (this.imgMoveY > this.imgMoveT) {
						this.imgMoveY = this.imgMoveT
					}
					if (this.imgMoveY < this.imgMoveB) {
						this.imgMoveY = this.imgMoveB
					}
				}
				// 是否展示动画
				this.imgTransition = true;
				this.setTransform()
			},
			// pc端鼠标点击事件
			mousedown(e){
				let data = [
					{
						pageX: e.pageX,
						pageY: e.pageY
					}
				]
				this._down(data)
			},
			// pc端鼠标移动
			mousemove(e){
				if(this.imgTransition) return;
				if(this.touchstartTouches.length > 0){
					this._move([
						{
							pageY: e.pageY,
							pageX: e.pageX
						}
					])
				}
				
			},
			//pc端鼠标抬起
			mouseup(){
				this.touchstartTouches = [];
				this._end()
			},
			// 手指触摸
			touchstart(e) {
				this._down([...e.touches])
			},
			// 手指移动
			touchmove(e) {
				this._move(e.touches)
			},
			// 手指结束 超出滚动区域了重置位置
			touchend(e) {
				this._end()
			},
			// 点击取消
			handleCancel() {
				this.reset()
				this.$emit('cancel')
				// uni.navigateBack()
			},
			reset(){
				this.imgMoveX = 0;
				this.imgMoveY = 0;
				this.imageSrc = '';
				this.imgTransition = false;
			},
			// 点击确定
			handleConfirm() {
				const _this = this;
				const ctx = uni.createCanvasContext('myCanvas');
				let x = (this.initData.left - this.imgMoveX + this.imgMaxLeft) * this.percentage;
				let y = (this.initData.top - this.imgMoveY + this.imgMaxTop) * this.percentage;
				let sWidth = this.roundW * this.percentage;
				// 计算比列调整画图的起始位置
				ctx.drawImage(_this.imageSrc, x, y, sWidth, sWidth, 0, 0, this.roundW, this.roundW)
				ctx.draw(true, () => {
					uni.canvasToTempFilePath({
						x: 0,
						y: 0,
						width: _this.roundW,
						height: _this.roundW,
						destWidth: _this.roundW,
						destHeight: _this.roundW,
						quality: 0.5,
						canvasId: 'myCanvas',
						success: function(res) {
							_this.$emit('success', res)
							_this.reset()
							_this.src_url = res.tempFilePath
						}
					})
				})
			}
		}
	}
</script>

<style lang="less" scoped>
	.page-view {
		position: fixed;
		height: 100vh;
		display: flex;
		flex-direction: column;
		z-index: 3;
		top: 0;
		left: 0;
		right: 0;


		.content-view {
			flex: 1;
			background-color: rgba(0, 0, 0, 1);
			overflow: hidden;
			position: relative;

			.img-view {
				position: absolute;
				inset: 0;

				.img {
					position: absolute;
					// top: 50%;
					// transform: translateY(-50%);

					&::after {
						content: '';
						position: absolute;
						inset: 0;
						background-color: rgba(0, 0, 0, 0.5);
					}
				}
			}

			.round-view {
				position: absolute;
				width: 600rpx;
				height: 600rpx;
				top: 50%;
				left: 50%;
				transform: translateY(-50%) translateX(-50%);
				overflow: hidden;
				box-shadow: 0 0 1rpx 1rpx rgba(255, 255, 255, 0.1);
				.round-img {
					position: absolute;
					left: calc((600rpx - 100vw)/2);
					// top: calc((600rpx - 100vh)/2);
				}
			}
		}
	}

	.footer-vtn {
		position: fixed;
		inset: auto 0 40rpx;
		display: flex;
		justify-content: space-around;

		.cancel-btn,
		.confirm-btn {
			padding: 10rpx 60rpx;
			border-radius: 10rpx;
			// box-shadow: 0 0 2px 2px blueviolet;
		}

		.cancel-btn {
			color: #999;
			box-shadow: 0 0 2px 2px #999;
		}

		.confirm-btn {
			color: #fff;
			background-color: rgba(25, 144, 255, 0.9);
			box-shadow: 0 0 2px 2px rgba(25, 144, 255, 0.9);
		}
	}

	.imgTransitionName {
		transition: all 0.1s ease-out;
	}
</style>